OpenCV 4 中文文档(更新mat部分)

您所在的位置:网站首页 opencv docs OpenCV 4 中文文档(更新mat部分)

OpenCV 4 中文文档(更新mat部分)

2023-03-11 14:57| 来源: 网络整理| 查看: 265

OpenCV 4 中文文档

原文https://www.docs.opencv.org/4.5.3/

目录 OpenCV 4 中文文档一、介绍一、API概念1. cv Namespace(cv名称空间)2. 自动内存管理3. 输出数据的自动分配4. 饱和算法5. 固定像素类型。模板的有限使用6. 输入阵列和输出阵列7. 错误处理8. 多线程和可重入性 二、OpenCV教程(OpenCV Tutorials)一、OpenCV的介绍二、核心功能(核心模块)- 库的基本组成部分1) Mat - 基本图像容器

一、介绍

OpenCV(开源计算机视觉库:http://opencv.org)是一个开源库,它包括数百种计算机视觉算法。该文件描述了OpenCV 2.x API,它本质上是一个C++ API,而不是基于C的OpenCV 1.x API(C API 自 OpenCV 2.4 发布以来已弃用且未使用"C"编译器进行测试)。

OpenCV 具有模块化结构,这意味着该包包括多个共享或静态库。提供以下模块:

核心功能(core):定义基本数据结构的紧凑型模块,包括密集的多维阵列 Mat 和所有其他模块使用的基本功能。图像处理(imgproc) : 图像处理模块,包括线性和非线性图像过滤、图像几何变换(大小、仿射和透视扭曲、基于通用表的重映射)、色彩空间转换、直方图等。视频分析(video):包括运动估计、背景消除和对象跟踪算法的视频分析模块。相机校准和 3D 重建(calib3d):基本的多视图几何算法、单声相机和立体相机校准、对象姿势估计、立体声通信算法和 3D 重建元素。2D 功能框架(features2d):显著特征探测器、描述符和描述符匹配器。对象检测(objdetect):检测预定类的对象和实例(例如,人脸、眼睛、杯子、人、汽车等)。高级GUI (highgui):简单UI功能的易用界面。视频 I/O (videoio ):易于使用的视频捕获和视频编解码器接口。其他一些辅助模块,如FLNN和谷歌测试包装器,Python绑定等。

文档的其他章节描述了每个模块的功能。但首先,请务必熟悉库中彻底使用的常见 API 概念。

一、API概念 1. cv Namespace(cv名称空间)

所有 OpenCV 类和函数都放在 cv 命名空间中。因此,要从您的代码访问此功能,请使用 cv:: 说明符或 using namespace cv; 标识:

#include "opencv2/core.hpp" ... cv::Mat H = cv::findHomography(points1, points2, cv::RANSAC, 5); ...

#include "opencv2/core.hpp" using namespace cv; ... Mat H = findHomography(points1, points2, RANSAC, 5 ); ...

某些当前或未来的 OpenCV 外部名称可能与 STL 或其他库冲突。在这种情况下,使用显式命名空间说明符来解决名称冲突:

Mat a(100, 100, CV_32F); randu(a, Scalar::all(1), Scalar::all(std::rand())); cv::log(a, a); a /= std::log(2.); 2. 自动内存管理

OpenCV 自动处理所有内存。 首先,函数和方法使用的 std::vector、cv::Mat和其他数据结构具有析构函数,可在需要时释放底层内存缓冲区。这意味着析构函数并不总是像 Mat 那样释放缓冲区。他们考虑了可能的数据共享。析构函数递减与矩阵数据缓冲区关联的参考计数器。当且仅当引用计数器达到零时,即当没有其他结构引用同一缓冲区时,才会释放缓冲区。类似地,当复制 Mat 实例时,并没有真正复制实际数据。相反,引用计数器递增以记住相同数据的另一个所有者。还有 Mat::clone方法可以创建矩阵数据的完整副本。请参阅下面的示例:

// create a big 8Mb matrix //创建一个大的 8Mb 矩阵 Mat A(1000, 1000, CV_64F); // create another header for the same matrix; // this is an instant operation, regardless of the matrix size. //为相同矩阵创建另一个标题; //这是一个即时操作,无论矩阵大小如何。 Mat B = A; // create another header for the 3-rd row of A; no data is copied either //为第3行创建另一个标题;任何一个数据都没有复制 Mat C = B.row(3); // now create a separate copy of the matrix //现在创建一个单独的矩阵副本 Mat D = B.clone(); // copy the 5-th row of B to C, that is, copy the 5-th row of A to the 3-rd row of A. //复制B的第5行到C,即复制A的第5行到A的第3行。 B.row(5).copyTo(C); // now let A and D share the data; after that the modified version of A is still referenced by B and C. //现在让A和D共享数据;之后修改了A仍被B和C引用的版本。 A = D; // now make B an empty matrix (which references no memory buffers), // but the modified version of A will still be referenced by C, // despite that C is just a single row of the original A //现在让B变为一个空矩阵(没有内存缓冲区的引用), //但A修改后的版本将仍然被C引用, //尽管C只是原来A中的一行 B.release(); // finally, make a full copy of C. As a result, the big modified // matrix will be deallocated, since it is not referenced by anyone //最后,制作C的完整副本。结果,大修改了 //矩阵将被释放,因为它没有被任何人引用 C = C.clone();

你看到使用 Mat 和其他基本结构很简单。但是在不考虑自动内存管理的情况下创建高级类甚至用户数据类型呢?对于他们而言,OpenCV提供了类似于C ++ 11的 std::hared_ptr 的 cv::Ptr 模板类。因此,不要使用普通指针:

T* ptr = new T(...);

你可以使用:

Ptr ptr(new T(...)); //或者 Ptr ptr = makePtr(...);

Ptr< T> 封装指向T实例的指针和与指针关联的引用计数器。有关详细信息,请参见 cv::Ptr 说明。

3. 输出数据的自动分配

OpenCV自动释放内存,并在大多数情况下自动为输出函数参数分配内存。因此,如果函数有一个或多个输入数组(例如cv::Mat)和一些输出数组,则输出数组将自动分配或重新分配。输出数组的大小和类型由输入数组的大小和类型决定。如果需要,这些函数将使用额外的参数来帮助确定输出数组属性。 例如:

#include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" using namespace cv; int main(int, char**) { VideoCapture cap(0); if(!cap.isOpened()) return -1; Mat frame, edges; namedWindow("edges", WINDOW_AUTOSIZE); for(;;) { cap >> frame; cvtColor(frame, edges, COLOR_BGR2GRAY); GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5); Canny(edges, edges, 0, 30, 3); imshow("edges", edges); if(waitKey(30) >= 0) break; } return 0; }

阵列帧由 >> 操作自动分配,因为视频捕获模块知道视频帧分辨率和位深度。阵列边缘由 cvtColor 函数自动分配。它与输入数组具有相同的大小和位深度。通道数为1,因为传递了颜色转换代码 cv::color_BGR2GRAY ,这意味着彩色到灰度的转换。注意,在循环体的第一次执行期间,帧和边仅分配一次,因为所有下一个视频帧具有相同的分辨率。如果您以某种方式更改视频分辨率,阵列将自动重新分配。 该技术的关键组件是 Mat::create 方法。它采用所需的数组大小和类型。如果数组已经具有指定的大小和类型,则该方法不执行任何操作。否则,它将释放先前分配的数据(如果有)(这部分涉及减少引用计数器并将其与零进行比较),然后分配所需大小的新缓冲区。大多数函数为每个输出数组调用 Mat::create 方法,因此实现了自动输出数据分配。 此方案的一些显著例外是 cv::MixChannel 、cv::RNG::fill 和其他一些函数和方法。他们无法分配输出数组,因此你必须提前这样做。

4. 饱和算法

作为一个计算机视觉库,OpenCV处理很多图像像素,这些像素通常以紧凑的、每通道8位或16位的形式编码,因此具有有限的值范围。此外,图像上的某些操作,如颜色空间转换、亮度/对比度调整、锐化、复杂插值(双立方插值、Lanczos)可能会产生超出可用范围的值。如果只存储结果的最低8(16)位,则会产生视觉伪影,并可能影响进一步的图像分析。为了解决这个问题,使用了所谓的饱和算法。例如,要将操作结果r存储到8位图像中,你可以找到0…255范围内最接近的值: I ( x , y ) = m i n ( m a x ( r o u n d ( r ) , 0 ) , 255 ) I(x,y)=min(max(round(r),0),255) I(x,y)=min(max(round(r),0),255) 类似的规则适用于8位有符号、16位有符号和无符号类型。这种语义在库中随处可见。在C++代码中,它使用类似于标准C++ CAST操作的 cv::saturate_cast 函数。见上文公式的实施情况:

I.at(y, x) = saturate_cast(r);

其中 cv::uchar 是OpenCV 8位无符号整数类型。在优化的SIMD代码中,使用了诸如ppaddusb, packuswb等SSE2指令。它们有助于实现与C++代码完全相同的行为。

注:当结果为32位整数时,不应用饱和。

5. 固定像素类型。模板的有限使用

模板是C++的一大特色,它能够实现非常强大、高效且安全的数据结构和算法。但是,模板的广泛使用可能会显著增加编译时间和代码大小。此外,如果只使用模板,则很难将接口和实现分开。这对于基本算法来说可能很好,但对于计算机视觉库来说并不好,因为在计算机视觉库中,单个算法可能跨越数千行代码。因此,为了简化其他语言(如Python、Java、Matlab)绑定的开发,这些语言根本没有模板或模板功能有限,当前的OpenCV实现基于多态性和运行时模板调度。在运行时调度太慢(如像素访问操作符)、不可能(通用 cv::Ptr 实现)或非常不方便( cv::saturate_cast() )的地方,当前的实现引入了小模板类、方法和函数。在当前OpenCV版本的任何其他地方,模板的使用都是有限的。 因此,库可以操作的基本数据类型集是有限的。也就是说,数组元素应具有以下类型之一:

8-bit unsigned integer (uchar)8-bit signed integer (schar)16-bit unsigned integer (ushort)16-bit signed integer (short)32-bit signed integer (int)32-bit floating-point number (float)64-bit floating-point number (double)多个元素的元组,其中所有元素都具有相同的类型(上述元素之一)。元素为元组的数组称为多通道数组,与元素为标量值的单通道数组相反。通道的最大可能数量由 CV_CN_MAX 常量定义,该常量当前设置为512。

对于这些基本类型,将应用以下枚举:

enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 };

可以使用以下选项指定多通道(n通道)类型:

CV_8UC1 … CV_64FC4常数(适用于从1到4的多个通道)CV_8UC(n)… CV_64FC(n)or CV_MAKETYPE(CV_8U, n)… CV_MAKETYPE(CV_64F, n) 编译时通道数大于4或未知时的宏。

注:CV_32FC1 == CV_32F, CV_32FC2 == CV_32FC(2) == CV_MAKETYPE(CV_32F, 2), and CV_MAKETYPE(depth, n) == ((depth&7) + ((n-1) const char* err_msg = e.what(); std::cout



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3